-- Rogue Rage
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
--
-- Darren Grey
-- http://gruesomegames.com

require "engine.class"
local DamageType = require "engine.DamageType"
local Map = require "engine.Map"
local Target = require "engine.Target"
local Talents = require "engine.interface.ActorTalents"
local Particles = require "engine.Particles"

--- Interface to add combat system
module(..., package.seeall, class.make)

--- Checks what to do with the target
-- Talk ? attack ? displace ?
function _M:bumpInto(target)

	if self.annoying then
		self.ranged = true
	end

	local reaction = self:reactionToward(target)
	if reaction < 0 then
		self:attackTarget(target)
	elseif reaction >= 0 then
		if self.move_others then
			-- Displace
			game.level.map:remove(self.x, self.y, Map.ACTOR)
			game.level.map:remove(target.x, target.y, Map.ACTOR)
			game.level.map(self.x, self.y, Map.ACTOR, target)
			game.level.map(target.x, target.y, Map.ACTOR, self)
			self.x, self.y, target.x, target.y = target.x, target.y, self.x, self.y
		end
	end
	
	self:useEnergy(game.energy_to_act)
end

function _M:attackTarget(target, dam)
	if self == game.player then game.player.crit = game.player.crit - 1 end
	local chance_to_hit = 50 + 10*self.aim - 10*target.dodge
	if chance_to_hit < 10 then chance_to_hit = 10 end
	if rng.range(1,100) < chance_to_hit then
		if ((self == game.player) and (rng.range(1,100) < game.player.crit)) then
			game.level.map:particleEmitter(target.x, target.y, 3, "ball_blood", {radius=3})
			self:project({type="ball",radius=3}, target.x, target.y, function(px, py)
				local t = game.level.map(px, py, engine.Map.ACTOR)
				if not t then return end

				if t ~= game.player then
					self:hitTarget(t,8+game.player.power)
				end
			end)
			game.player.crit = 0
		else
			local damage = self.power - target.armour
			if damage < 1 then damage = 1 end
			self:hitTarget(target,damage)
			self:setMoveAnim(self.x, self.y, 4, nil, util.getDir(target.x, target.y, self.x, self.y), 0.8)
		end
	else
		-- miss animation
		target:setMoveAnim(target.x, target.y, 4, nil, 8, 0.2)
	end
end

--- Makes the death happen!
function _M:hitTarget(target, dam)
	local co = coroutine.create(function()
	
	if (target.life > 0) then
		local sx, sy = game.level.map:getTileToScreen(target.x, target.y)

		-- Insert sounds to hits (kill sounds go in on_die)
		if target:takeHit(dam, self) then
				game.level.map:particleEmitter(target.x, target.y, 1, "death")
				
				if target.faction == "enemies" then
					game.player.no_enemies = game.player.no_enemies - 1
					game.flyers:add(sx, sy, 20, (rng.range(0,3)-1) * 0.5, -4, ("+%d"):format(target.score), {240, 240, 120})
					game.player.score_this_round = game.player.score_this_round + target.score
					game.player.kills_this_round = game.player.kills_this_round + 1
				end
		else
			game.level.map:particleEmitter(target.x, target.y, 1, "melee_attack", {color=self.color})
			--game.level.map:particleEmitter(target.x, target.y, 1, "melee_attack", {color={r=210,g=10,b=10}})
			if target == game.player then game.player.crit = game.player.crit + 1 end
			if target.return_damage > 0 then self:hitTarget(self,target.return_damage) end
			
			if self.pushy > 0 then
				local recursive = function(target)
					return true
				end
				target:knockback(self.x, self.y, 1, recursive)
				target:setMoveAnim(target.x, target.y, 4, nil, util.getDir(self.x, self.y, target.x, target.y), 0.35)
			end
			
			if self.vampiric > 0 then
				local heal = self.vampiric
				if heal > dam then heal = dam end
				self.life = self.life + heal
				if self.life > self.max_life then self.life = self.max_life end
			end
		end

	end

   end)

	coroutine.resume(co)

end
